package Test;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by SinceZero on 2017/12/24.
 */
public class BanJiTest {
    public static void main(String[] args) {
        BanJi ban = new BanJi();
        Map<String, String> map = new HashMap<>();
        map.put("className", "高一七班");
        map.put("teacher", "张**");
        map.put("studentCount", "3");
        map.put("name_0", "张三");
        map.put("name_1", "李四");
        map.put("name_2", "王五");
        map.put("gender_0", "男");
        map.put("gender_1", "女");
        map.put("gender_2", "男");
        mapToBean2(map, ban);
    }
    public static<T> void mapToBean2(Map<String, String> map, T bean) {
        if (map == null || bean == null) {
            return;
        }
        try {
            Class beanClass = bean.getClass();
            BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            Field[] fields = beanClass.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.getType() == java.util.List.class) {
                    Type genericType= field.getGenericType();
                    if (genericType instanceof ParameterizedType) {
                        ParameterizedType pt = (ParameterizedType) genericType;
                        Class genericClazz = (Class) pt.getActualTypeArguments()[0];
                        Map<Integer, Map<String, String>> listMap = getListMap(map);
                        List propertyList = new ArrayList();
                        for (Map.Entry<Integer, Map<String, String>> entry : listMap.entrySet()) {
                            Object subBean = genericClazz.newInstance();
                            mapToBean(entry.getValue(), subBean);
                            propertyList.add(subBean);
                        }
                        field.set(bean, propertyList);
                    }
                    break;
                }
            }
            for (PropertyDescriptor property : propertyDescriptors) {
                String propertyName = property.getName();
                Class clazz = property.getPropertyType();
                if (clazz.getName().equals("java.util.List")) {
                    System.out.println(clazz.getComponentType());
                }
                if (map.containsKey(propertyName)) {
                    String value = map.get(propertyName);
                    Method setter = property.getWriteMethod();
                    setter.invoke(bean, value);
                }
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
    public static<T> void mapToBean(Map<String, String> map, T bean) {
        if (map == null || bean == null) {
            return;
        }
        try {
            Class beanClass = bean.getClass();
            BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String propertyName = property.getName();
                if (map.containsKey(propertyName)) {
                    String value = map.get(propertyName);
                    Method setter = property.getWriteMethod();
                    setter.invoke(bean, value);
                }
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static Map getListMap(Map<String, String> map) {
        Map<Integer, Map<String, String>> returnMap = new HashMap<>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String propertyName = entry.getKey();
            if (propertyName.matches("^.*_\\d$")) {
                int index = Integer.parseInt(propertyName.substring(propertyName.length() - 1));
                String newKey = entry.getKey().split("_\\d$")[0];
                if (!returnMap.containsKey(index)) {
                    Map<String, String> listMap = new HashMap<>();
                    listMap.put(newKey, entry.getValue());
                    returnMap.put(index, listMap);
                } else {
                    returnMap.get(index).put(newKey, entry.getValue());
                }
            }
        }
        return returnMap;
    }
}
